package com.haoze.common.utils;

import com.google.common.base.Joiner;
import com.haoze.common.dto.CronDescriber;
import com.haoze.common.enumeration.StateEnum;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: gzc
 * @Date: 2020/3/18 10:40
 */
public class CronUtil {
    private static final Logger logger = LoggerFactory.getLogger(CronUtil.class);

    public static String createCronExpression(CronDescriber scheduleModel, Date startDate){
        StringBuffer cronExp = new StringBuffer("");
        scheduleModel.setSpecifiedDows(scheduleModel.getSpecifiedDows().stream().filter(Objects::nonNull).collect(Collectors.toList()));
        if(null==scheduleModel){
            return "";
        }
            String d ="";
            String h ="";
            String m ="";
        //获取开始时间的时，分，天
        if(null!=startDate){
            d =String.format("%td", startDate);
            h =String.format("%tH", startDate);
            m =String.format("%tM", startDate);
        }


        //设置秒位
        cronExp.append("0 ");

        //设置分钟
        //判断分钟类型
        if(StateEnum.MINUTE_TYPE_0.getValue().equals(scheduleModel.getMinuteType().toString())){
            //间隔分钟
            if(StringUtils.isBlank(m)){
                cronExp.append("*/"+scheduleModel.getMinuteInterval()+" ");
            }else {
                cronExp.append(m+"/"+scheduleModel.getMinuteInterval()+" ");
            }
        }else if(StateEnum.MINUTE_TYPE_1.getValue().equals(scheduleModel.getMinuteType().toString())&&!scheduleModel.getSpecifiedMinutes().isEmpty()){
            //指定时间
            cronExp.append(Joiner.on(",").join(scheduleModel.getSpecifiedMinutes())+" ");
        }else{
            //不指定分钟
            cronExp.append("0 ");
        }

        //设置小时
        //判断小时类型
        if(StateEnum.HOUR_TYPE_0.getValue().equals(scheduleModel.getHourType().toString())){
            //间隔小时
            if(StringUtils.isBlank(h)){
                cronExp.append("*/"+scheduleModel.getHourInterval()+" ");
            }else {
                cronExp.append(h+"/"+scheduleModel.getHourInterval()+" ");
            }
        }else if(StateEnum.HOUR_TYPE_1.getValue().equals(scheduleModel.getHourType().toString())&&!scheduleModel.getSpecifiedHours().isEmpty()){
            //指定整点
            cronExp.append(Joiner.on(",").join(scheduleModel.getSpecifiedHours())+" ");
        }else{
            //晚上0点
            cronExp.append("0 ");
        }

        //设置天
        //判断天数类型
        if(StateEnum.DAY_TYPE_0.getValue().equals(scheduleModel.getDayType().toString())){
            //间隔天数
            if(StringUtils.isBlank(d)){
                cronExp.append("*/"+scheduleModel.getDayInterval()+" ");
            }else {
                cronExp.append(d+"/"+scheduleModel.getDayInterval()+" ");
            }
            //补全表达式
            cronExp.append("* ");
            cronExp.append("? ");
        }else if(StateEnum.DAY_TYPE_1.getValue().equals(scheduleModel.getDayType().toString())&&!scheduleModel.getSpecifiedDows().isEmpty()){
            //指定星期
            //补全表达式
            cronExp.append("? ");
            cronExp.append("* ");
            cronExp.append(Joiner.on(",").join(scheduleModel.getSpecifiedDows())+"");
        }else{
            //每天
            cronExp.append("? ");
            //补全表达式
            cronExp.append("* ");
            cronExp.append("* ");
        }
        return cronExp.toString();
    }

    public static String createDescription(CronDescriber scheduleModel, Date startDate){
        StringBuffer cronExp = new StringBuffer("");
        if(null==scheduleModel){
            return "";
        }
        if(startDate!=null){
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            cronExp.append("从"+dateFormat.format(startDate)+"开始,");
        }
        //设置天
        //判断天数类型
        if(StateEnum.DAY_TYPE_0.getValue().equals(scheduleModel.getDayType().toString())){
            //间隔天数
            if(scheduleModel.getDayInterval()==1){
                cronExp.append("每天");
            }else{
                cronExp.append("每"+scheduleModel.getDayInterval().toString()+"天");
            }
        }else if(StateEnum.DAY_TYPE_1.getValue().equals(scheduleModel.getDayType().toString())&&!scheduleModel.getSpecifiedDows().isEmpty()){
            //指定星期
            cronExp.append("每周"+Joiner.on(",").join(toWeek(scheduleModel.getSpecifiedDows()))+"");
        }


        //设置小时
        //判断小时类型
        if(StateEnum.HOUR_TYPE_0.getValue().equals(scheduleModel.getHourType().toString())){
            if(cronExp.length()==0){
                cronExp.append("每"+(scheduleModel.getHourInterval()==1?"":scheduleModel.getHourInterval())+"小时");
            }else{
                cronExp.append(",每"+(scheduleModel.getHourInterval()==1?"":scheduleModel.getHourInterval())+"小时");
            }
        }else if(StateEnum.HOUR_TYPE_1.getValue().equals(scheduleModel.getHourType().toString())&&!scheduleModel.getSpecifiedHours().isEmpty()){
            //指定整点
            if(cronExp.length()==0){
                cronExp.append(Joiner.on(",").join(to12Time(scheduleModel.getSpecifiedHours())));
            }else{
                cronExp.append(","+Joiner.on(",").join(to12Time(scheduleModel.getSpecifiedHours())));

            }
        }


        //设置分钟
        //判断分钟类型
        if(StateEnum.MINUTE_TYPE_0.getValue().equals(scheduleModel.getMinuteType().toString())){
                //间隔分钟
            if(cronExp.length()==0){
                cronExp.append("每"+(scheduleModel.getMinuteInterval()==1?"":scheduleModel.getMinuteInterval())+"分钟");
            }else {
                cronExp.append(",每"+(scheduleModel.getMinuteInterval()==1?"":scheduleModel.getMinuteInterval())+"分钟");
            }
        }else if(StateEnum.MINUTE_TYPE_1.getValue().equals(scheduleModel.getMinuteType().toString())&&!scheduleModel.getSpecifiedMinutes().isEmpty()){
            //指定时间
            if(cronExp.length()==0){
                cronExp.append(Joiner.on("分,").join(scheduleModel.getSpecifiedMinutes())+"分");
            }else{
                cronExp.append(","+Joiner.on("分,").join(scheduleModel.getSpecifiedMinutes())+"分");
            }
        }
        if(cronExp.length()>0){
            cronExp.append(",一次");
        }
        return cronExp.toString();
    }


    private static String toChinese(String str) {
        String[] s = {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
        StringBuffer sb=new StringBuffer();
        for (char c : str.toCharArray()) {
            sb.append(s[Integer.parseInt(String.valueOf(c))]);
        }
        return sb.toString();
    }
    private static List<String> toWeek(List<String> list) {
        List<String> weekList = new ArrayList<>();
        list.stream().forEach(str ->{
            String day="";
            switch (str) {
                case ("SUN"):
                    day="星期日";
                    break;
                case "MON":
                    day="星期一";
                    break;
                case "TUE":
                    day="星期二";
                    break;
                case "WED":
                    day="星期三";
                    break;
                case "THU":
                    day="星期四";
                    break;
                case "FRI":
                    day="星期五";
                    break;
                case "SAT":
                    day="星期六";
                    break;
                default:
                    day="";
            }
            weekList.add(day);
        });
        return weekList;
    }

    private static List<String> to12Time(List<Integer> hours) {
        List<String> timeList = new ArrayList<>();
        hours.stream().forEach(hour ->{
            String time="";
            if(hour<12){
                time="上午"+hour+"点";
            }else if(hour>12){
                time="下午"+(hour-12)+"点";
            }else{
                time="中午12点";
            }
            timeList.add(time);
        });

        return timeList;
    }

    public static final Map<String, String> DOW_MAP = new HashMap<>();

    static {
        DOW_MAP.put("SUN", "7");
        DOW_MAP.put("MON", "1");
        DOW_MAP.put("TUE", "2");
        DOW_MAP.put("WED", "3");
        DOW_MAP.put("THU", "4");
        DOW_MAP.put("FRI", "5");
        DOW_MAP.put("SAT", "6");

    }

    public static String hisConverter(CronDescriber describer) {
        String hisExecTime = "";
        try {
            if (null != describer.getHourEnabled() && null != describer.getHourType() && describer.getHourEnabled() && CronDescriber.TYPE_SPECIFIED.equals(describer.getHourType())) {
                hisExecTime += describer.getSpecifiedHours().stream().filter(Objects::nonNull).map(i -> String.format("%02d", i)).collect(Collectors.joining("-"));
            }
            if( null != describer.getSpecifiedDows()) {
                long dayCount = describer.getSpecifiedDows().stream().filter(StringUtils::isNotEmpty).count();
                if (null != describer.getDayEnabled()
                        && null != describer.getDayType()
                        && describer.getDayEnabled()
                        && CronDescriber.TYPE_SPECIFIED.equals(describer.getDayType())
                        && dayCount > 0) {
                    hisExecTime += "//" + dayCount + "/1周(" + describer.getSpecifiedDows().stream().filter(StringUtils::isNotEmpty).map(DOW_MAP::get)
                            .sorted().collect(Collectors.joining()) + ")";
                    if (describer.getLast() != null) {
                        DecimalFormat df = new DecimalFormat("#####.##");
                        hisExecTime += "//持续" + df.format(describer.getLast()) + describer.getLastUnit();
                    }
                }
            }
        } catch (Exception e) {
            logger.error("解析出错", e);
        }
        return hisExecTime;
    }

}
